/*
 * 代号：凤凰
 * http://www.jphenix.org
 * 2014-06-12
 * V4.0
 */
package com.jphenix.share.util;

import com.jphenix.share.lang.SDouble;
import com.jphenix.share.lang.SInteger;
import com.jphenix.share.lang.SString;
import com.jphenix.standard.docs.ClassInfo;

import java.lang.reflect.Array;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 基本方法
 * com.jphenix.share.util.BaseUtil
 * 
 * 2018-08-15 增加了toList(array)方法
 * 2018-08-16 增加了 keyList(Map) 方法，等同于 getMapKeyList(Map)
 * 2018-09-17 增加了swap简化了名字的方法
 * 2022-05-24 增加了磁盘空间数据显示方法
 * 
 * 创建日期 2005-10-13 16:31:31
 * @author 刘虻
 */
@ClassInfo({"2022-05-24 16:13","基本方法"})
public class BaseUtil {
	
	/**
	 * 从字符串之间的一点分割为两个字符串 分割点算第二个字符串
	 * @author 刘虻
	 * @param source 原字符串
	 * @param point 分割字符串
	 * @return 分割后的字符串数组
	 * 2006-7-20  18:23:03
	 */
	public static String[] cutStringOutPoint(
					String source,String point) {
		
		//导入参数合法化
		if (source == null 
				|| point == null 
				|| point.length()==0) {
			return null;
		}
		//获得第一个位置
		int pointNo = source.indexOf(point);
		return cutStringOutPoint(source,pointNo);
	}
	
	
	/**
	 * 从字符串之间的一点分割为两个字符串 分割点算第二个字符串
	 * 从最后开始扫描
	 * @author 刘虻
	 * @param source 原字符串
	 * @param point 分割字符串
	 * @return 分割后的字符串数组
	 * 2006-7-20  18:23:03
	 */
	public static String[] cutStringOutPointFromLast(
					String source,String point) {
		
		//导入参数合法化
		if (source == null 
				|| point == null 
				|| point.length()==0) {
			return null;
		}
		//转换为小写
		point = point.toLowerCase();
		//获得第一个位置
		int pointNo = source.toLowerCase().lastIndexOf(point);
		return cutStringOutPoint(source,pointNo);
	}
	
	
	/**
	 * 返回源字符串中包含目标字符串的数量
	 * @author 刘虻
	 * @param source 源字符串
	 * @param key 目标字符串
	 * @return 数量
	 * 2006-7-20  21:00:49
	 */
	public static int inStringCount(String source,String key) {
		//导入参数合法化
		if (source == null 
				|| source.length()==0 
				|| key == null 
				|| key.length()==0) {
			return 0;
		}
		int count = 0; //构建返回值
		while (true) {
			
			String[] cuts = 
				cutStringIncPoint(source,key);
			if (cuts != null 
					&& cuts[0] != null 
					&& cuts[0].length()>0) {
				source = cuts[1];
				count++;
				continue;
			}
			break;
		}
		return count;
	}
	
	
	/**
	 * 去掉字符串两边的引号
	 * @author 刘虻
	 * @param source 源字符串
	 * @return  截取到前后引号中间的字符串
	 * 2006-7-20  21:10:40
	 */
	public static String fixMark(String source) {
		int singleMark = source.indexOf("'");
		int doubleMark = source.indexOf("\"");
		String fixChar = null; //准备去掉的字符
		if (singleMark < 0 && doubleMark < 0) {
			return source;
		}else if (doubleMark < 0 && singleMark > -1){
			fixChar = "'";
		}else if (singleMark < 0 && doubleMark > -1) {
			fixChar = "\"";
		}else if (doubleMark < singleMark) {
			fixChar = "\"";
		}else {
			fixChar = "'";
		}
		if (fixChar != null) {
			//截取到前后fixChar中间的字符串
			source = 
				source.substring(
						source.indexOf(fixChar)+1);
			if (source.lastIndexOf(fixChar)>=0) {
			source = source.substring(0,source.lastIndexOf(fixChar));
			}
		}
		return source;
	}
	
	
	/**
	 * 将序列中的字符串由长到短进行排序
	 * @author 刘虻
	 * 2007-1-9下午04:33:26
	 * @param sourceArrayList 原字符串序列
	 * @return 排序后的字符串序列
	 */
	public static ArrayList<String> orderByDescString(List<String> sourceArrayList) {
		//构造返回值
		ArrayList<String> reArrl = new ArrayList<String>();
		//获取由短到长的排序
		ArrayList<String> ascArrl = orderByAscString(sourceArrayList);
		for (int i=ascArrl.size()-1;i>-1;i--) {
			reArrl.add(ascArrl.get(i));
		}
		return reArrl;
	}
	
	/**
	 * 将序列中的字符串由短到长进行排序
	 * @author 刘虻
	 * 2007-1-9下午04:01:58
	 * @param sourceArrayList 原字符串序列
	 * @return 排序后的字符串序列
	 */
	public static ArrayList<String> orderByAscString(List<String> sourceArrayList) {
		//构造返回值
		ArrayList<String> reArrl = new ArrayList<String>();
		if (sourceArrayList!=null) {
			for (String srcKey:sourceArrayList) {
				if (srcKey==null) {
					srcKey="";
				}
				int point = 0; //插入位置指针
				boolean finded = false; //没有找到合适的中间位置
				for (int j=0;j<reArrl.size();j++) {
					if (reArrl.get(j).length()>srcKey.length()) {
						finded = true;
						break;
					}
					point++;
				}
				if (!finded) {
					reArrl.add(srcKey);
				}else {
					reArrl.add(point,srcKey);
				}
			}
		}
		return reArrl;
	}
	
	
	/**
	 * 将序列中的字符串由长到短进行排序
	 * 字符串开头相同的排在一起
	 * @author 刘虻
	 * 2007-1-9下午04:33:26
	 * @param sourceArrayList 原字符串序列
	 * @return 排序后的字符串序列
	 */
	public static ArrayList<String> orderByDescStringPro(List<String> sourceArrayList) {
		//构造返回值
		ArrayList<String> reArrl = new ArrayList<String>();
		//获取由短到长的排序
		ArrayList<String> ascArrl = orderByAscStringPro(sourceArrayList);
		for (int i=ascArrl.size()-1;i>-1;i--) {
			reArrl.add(ascArrl.get(i));
		}
		return reArrl;
	}
	
	
	/**
	 * 将序列中的字符串进行又短到长排序
	 * 
	 * 字符串开头相同的排在一起
	 * 
	 * @author 刘虻
	 * 2007-1-9下午04:21:53
	 * @param sourceArrayList 原字符串
	 * @return 排序后的字符串
	 */
	public static ArrayList<String> orderByAscStringPro(List<String> sourceArrayList) {
		//整理成由短到长排序后的序列
		ArrayList<String> keyArrl = orderByAscString(sourceArrayList);
		if (keyArrl==null || keyArrl.size()<1) {
			return new ArrayList<String>();
		}
		//整理后的路径容器
		HashMap<String,ArrayList<String>> fixPathHasm = new HashMap<String,ArrayList<String>>();
		String key;
		ArrayList<String> elementArrl;
		while(keyArrl.size()>0) {
			key = keyArrl.get(0);
			keyArrl.remove(0);
			elementArrl = new ArrayList<String>();
			elementArrl.add(key);
			fixPathHasm.put(key,elementArrl);
			if (keyArrl.size()<1) {
				break;
			}
			String objKey;
			for (int i=0;i<keyArrl.size();i++) {
				objKey = keyArrl.get(i);
				if (objKey.startsWith(key)) {
					keyArrl.remove(i);
					(fixPathHasm.get(key)).add(objKey);
					i--;
				}
			}
		}
		//构造返回值
		ArrayList<String> reArrl = new ArrayList<String>();
		//放入排序后的元素
		Object[] keys = getMapKeys(fixPathHasm);
		if(keys!=null) {
		    ArrayList<String> element;
			for (int i=0;i<keys.length;i++) {
				element = fixPathHasm.get(keys[i]);
				for (int j=0;j<element.size();j++) {
					reArrl.add(element.get(j));
				}
			}
		}
		return reArrl;
	}
	
	
	/**
	 * 从字符串之间的一点分割为两个字符串 分割点算第二个字符串
	 * @author 刘虻
	 * @param source 原字符串
	 * @param point 分割点位置
	 * @return 分割后的字符串数组
	 * 2006-7-20  18:23:03
	 */
	public static String[] cutStringOutPoint(String source,int point) {
		//构造返回值
		String[] reStrs = new String[2];
		if (source == null) {
			return reStrs;
		}
		//分割点大于字符串长度，将源字符串算第一个元素的
		if (point > source.length()){
			reStrs[0] = source;
			return reStrs;
		}
		//如果分割点小于0，将源字符串算第二个元素的
		if (point < 0){
			reStrs[1] = source;
			return reStrs;
		}
		reStrs[0] = source.substring(0,point); //头
		reStrs[1] = source.substring(point); //尾
		return reStrs;	
	}
	
	
	/**
	 * 从字符串之间的一点分割为两个字符串 数组元素不包括分割点
	 * @author 刘虻
	 * @param source 原字符串
	 * @param point 分割点
	 * @return 分割后的数组
	 * 2006-7-20  21:33:47
	 */
	public static String[] cutStringWithoutPoint(String source,String point) {
		//构造返回值
		String[] reStrs = new String[2];
		if (source == null 
				|| point == null 
				|| point.length()==0) {
			return reStrs;
		}
		//获取第一个位置
		int pointNo = source.indexOf(point);
		//分割点大于字符串长度，将源字符串算第一个元素的
		if (pointNo > source.length()){
			reStrs[0] = source;
			return reStrs;
		}
		//如果分割点小于0，将源字符串算第二个元素的
		if (pointNo < 0){
			reStrs[1] = source;
			return reStrs;
		}
		reStrs[0] = source.substring(0,pointNo); //头
		if (pointNo+point.length() < source.length()) {
			reStrs[1] = source.substring(pointNo+point.length()); //尾
		}else {
			reStrs[1] = "";
		}
		return reStrs;	
	}
	
	
	/**
	 * 将数组转换成ArrayList
	 * @author 刘虻
	 * 2007-9-5下午07:06:42
	 * @param array 源数组
	 * @return ArrayList
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static ArrayList arrayToArrayList(Object array) {
		//构建返回值
		ArrayList reList = new ArrayList();
		if (array==null
				|| !array.getClass().getName().startsWith("[")) {
			return reList;
		}
		//获取数组大小
		int size = Array.getLength(array);
		for (int i=0;i<size;i++) {
			reList.add(Array.get(array,i));
		}
		return reList;
	}
	
	/**
	 * 将数组转换成ArrayList
	 * @author 刘虻
	 * 2018-08-15 17:22:00
	 * @param array 源数组
	 * @return ArrayList 对应的序列
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static List toList(Object array){
		//构建返回值
		ArrayList reList = new ArrayList();
		if (array==null
				|| !array.getClass().getName().startsWith("[")) {
			return reList;
		}
		//获取数组大小
		int size = Array.getLength(array);
		for (int i=0;i<size;i++) {
			reList.add(Array.get(array,i));
		}
		return reList;
	}
	
	/**
	 * 将ArrayList转换为对应类型的数组
	 * @author 刘虻
	 * 2007-9-5下午07:11:57
	 * @param arrayList 源ArrayList
	 * @param returnCls 返回数组类型
	 * @return 转换后的数组
	 */
	public static Object listToArray(List<?> list,Class<?> returnCls) {
		if (returnCls==null) {
			return null;
		}
		//数组元素数
		int size = 0;
		if (list!=null) {
			size = list.size();
		}
		//构建返回值数组
		Object reObj = Array.newInstance(returnCls,size);
		for(int i=0;i<size;i++) {
			Array.set(reObj,i,list.get(i));
		}
		return reObj;
	}
	
	/**
	 * 将字符串序列转换为字符串数组
	 * @param list 字符串序列
	 * @return 字符串数组
	 * 2014年10月16日
	 * @author 马宝刚
	 */
	public static String[] listToArray(List<String> list) {
	    if(list==null) {
	        return new String[0];
	    }
	    //构建返回值
	    String[] reArr = new String[list.size()];
	    for(int i=0;i<list.size();i++) {
	        reArr[i] = list.get(i);
	    }
	    return reArr;
	}

	
	/**
	 * 获取整型数组中最小值的数组索引
	 * @author 刘虻
	 * 2009-8-20下午03:31:00
	 * @param src 整型值数组
	 * @param min 最小值
	 * @return 最小值索引
	 */
	protected static int getMinIndex(int[] src,int min) {
		int thisMin = min; //最小值
		int reInt = -1; //最小值索引
		for(int i=0;i<src.length;i++) {
			if(min<src[i] && (thisMin>src[i] || thisMin==min)) {
				thisMin = src[i];
				reInt = i;
			}
		}
		return reInt;
	}
	
	
	/**
	 * 按照指定字符串数组将源字符串分割为序列
	 * @author 刘虻
	 * 2009-8-20下午03:34:25
	 * @param source 源字符串
	 * @param points 分割字符串数组
	 * @return 分割后的序列
	 */
	public static List<String> splitToList(String source,String... points) {
		if (source==null || source.length()==0 
				|| points==null || points.length<1) {
			return new ArrayList<String>();
		}
		//构造返回容器
		List<String> reArrl = new ArrayList<String>();
		//构建分割点
		int[] indexs = new int[points.length];
		for(int i=0;i<indexs.length;i++) {
			indexs[i] = source.indexOf(points[i]);
		}
		int index; //最小位置值
		while(true) {
			//获取最小值
			index = getMinIndex(indexs,-1);
			if(index<0) {
				reArrl.add(source);
				break;
			}
			reArrl.add(source.substring(0,indexs[index]));
			//构造分割后的字符串
			source = 
				source.substring(indexs[index]+points[index].length());
			for(int i=0;i<indexs.length;i++) {
				indexs[i] = source.indexOf(points[i]);
			}
		}
		return reArrl;
	}
	
	
	/**
	 * 从字符串之间的一点分割为两个字符串 分割点算第一个字符串
	 * @author 刘虻
	 * @param source 原字符串
	 * @param point 分割点位置
	 * @return 分割后的字符串数组
	 * 2006-7-20  18:23:03
	 */
	public static String[] cutStringIncPoint(String source,String point) {
		
		//构造返回值
		String[] reStrs = new String[2];
		
		if (source == null 
				|| point == null 
				|| point.length()==0) {
			return reStrs;
		}
		
		//获取第一个位置
		int pointNo = source.indexOf(point)+point.length();
		
		//分割点大于字符串长度，将源字符串算第一个元素的
		if (pointNo > source.length()){
			reStrs[0] = source;
			return reStrs;
		}
		//如果分割点小于0，将源字符串算第二个元素的
		if (pointNo < 0){
			reStrs[1] = source;
			return reStrs;
		}
		
		reStrs[0] = source.substring(0,pointNo); //头
		reStrs[1] = source.substring(pointNo); //尾
		
		return reStrs;	
	}
	
	
	/**
	 * mark1和mark2标签通常在source中是嵌套的
	 * 此方法截取最外层标签，放在数组0中，剩下的放在数组1中
	 * <a>
	 * 		<a>
	 * 			<a>
	 * 			</a>
	 * 		</a>
	 * 		<a>
	 * 		</a>
	 * </a>
	 * <a>
	 * </a>
	 * 
	 * @author 刘虻
	 * @param source 源信息
	 * @param mark1 标签开始标识
	 * @param mark2 标签结束标识
	 * @return 0截取字符，1剩下的字符
	 * 2006-7-21  12:10:53
	 */
	public static String[] cutDobutMarkString(
			String source,String mark1,String mark2) {
		
		//导入参数合法化
		if (source == null 
				|| source.length()==0 
				|| mark1 == null 
				|| mark1.length()==0 
				|| mark2 == null 
				|| mark2.length()==0) {
			return null;
		}
		String[] reStrs = new String[2];
		
		String fixString = source;
		int no = 0;
		int point = 0; //截取点
		while (fixString.length() > 0) {
			int point1 = fixString.indexOf(mark1);
			int point2 = fixString.indexOf(mark2);
			String[] cuts = null;
			if (point2 > -1) {
				if (point2 > point1 && point1 > -1) {
					no++;
					cuts = cutStringIncPoint(fixString,mark1);
				}else {
					no--;
					cuts = cutStringIncPoint(fixString,mark2);
				}
				
				if (cuts != null) {
					fixString = cuts[1];
					if (cuts[0].length() > 0) {
					    point += cuts[0].length();
					}
				}
			}else {
				System.err.println(
						"截取字符串发生异常BaseUtil.cutDobutMarkString\nmark1:"
				        +mark1+"\nmark2:"+mark2+"\nsource:\n"+source);
				return null;
			}
			if (no==0) {
				break;
			}
		}
		if (fixString.length()>0) {
		    reStrs[0] = source.substring(0,point);
		    reStrs[1] = source.substring(point);
		}else {
			reStrs[0] = source;
		}
		
		
		return reStrs;
	}
	
	
	/**
	 * 从字符串之间的一点分割为两个字符串 分割点算第一个字符串
	 * 目标字符串从源字符串的最后开始查找 
	 * @author 刘虻
	 * @param source 原字符串
	 * @param point 分割点位置
	 * @return 分割后的字符串数组
	 * 2006-7-20  18:23:03
	 */
	public static String[] cutStringIncPointFromLast(String source,String point) {
		
		//构造返回值
		String[] reStrs = new String[2];
		
		if (source == null 
				|| point == null 
				|| point.length()==0) {
			return reStrs;
		}
		
		//获取第一个位置
		int pointNo = source.lastIndexOf(point)+point.length();
		
		//分割点大于字符串长度，将源字符串算第一个元素的
		if (pointNo > source.length()){
			reStrs[0] = source;
			return reStrs;
		}
		//如果分割点小于0，将源字符串算第二个元素的
		if (pointNo < 0){
			reStrs[1] = source;
			return reStrs;
		}
		
		reStrs[0] = source.substring(0,pointNo); //头
		reStrs[1] = source.substring(pointNo); //尾
		
		return reStrs;	
	}
	
	
	/**
	 * 获得当前时间
	 * @author 刘虻
	 * @return 返回可视格式的当前时间
	 * 2006-04-07  15:15:39
	 */
	public static String getNowTime() {
    	SimpleDateFormat sdmObj = 
    	    new SimpleDateFormat("HH:mm:ss:S");
    	return sdmObj.format(new Date());
	}
	
	
	/**
	 * 获得当前日期
	 * @author 刘虻
	 * @return 返回可视格式的当前日期
	 * 2006-04-07  15:15:39
	 */
	public static String getNowDate() {
    	SimpleDateFormat sdmObj = 
    	    new SimpleDateFormat("yyyy-MM-dd EEE");
    	return sdmObj.format(new Date());
	}
	
	/**
	 * 判断指定内容是否为数字
	 * @author 刘虻
	 * @param str 被判断的字符串
	 * @return
	 * 2005-10-13  16:34:11
	 */
	public static boolean isNumber(String str) {
		
		try {
			Double.parseDouble(str);
			return true;
		}catch (Exception e) {
			return false;
		}
	}
	
	
	

	/**
	 * 打印当前堆栈信息
	 * @author 刘虻
	 * @param obj 当前类实例
	 * 2006-8-6  13:14:48
	 */
	public static void printStackTraceString(Object obj) {
	    //输出堆栈信息
	    System.err.println(getStackTraceString(obj));
	    return;
	}
	
	
	/**
	 * 将字符串按照指定字符分割为字符串数组
	 * @author 刘虻
	 * 2006-10-26下午11:54:09
	 * @param source 原字符串
	 * @param splitStr 指定分割字符
	 * @return 分割后的字符串数组
	 */
	public static String[] split(String source,String... splitStr) {
		//获取分割后的序列
		List<String> reArrl = splitToList(source,splitStr);
		//构件返回值
		String[] reStrs = new String[reArrl.size()];
		//复制值
		reArrl.toArray(reStrs);
		return reStrs;
	}
	
	
	/**
	 * 获取当前类的堆栈信息
	 * @author 刘虻
	 * @param obj 当前类
	 * @return 当前类的堆栈信息
	 * 2006-8-9  14:04:58
	 */
	public static String getStackTraceString(Object obj) {
	    //构造返回值
	    StringBuffer reSbf = new StringBuffer();
	    //导入参数合法化
	    if (obj == null) {
	        return "";
	    }
	    //构造堆栈
	    Throwable throwable = new Throwable();
	    reSbf.append("类："+obj.getClass().getName()+":\n");
	    reSbf.append(obj.toString()).append("\n");
	    //构造堆栈深度
	    int stackTraceCount = throwable.getStackTrace().length;
	    //构造堆栈信息
        for(int i=0; i < stackTraceCount; i++){
            //堆栈行
            StackTraceElement stacktraceelement = throwable.getStackTrace()[i];
            reSbf.append(
                    "类：行["+stacktraceelement.getClassName()
                    +":"+stacktraceelement.getLineNumber()+"]\n");
        }
	    return reSbf.toString();
	}
	
	/**
	 * 获得当前程序堆栈信息
	 * @author 刘虻
	 * @param traceLevelInt 堆栈深度  从当前行，的上一级为1  再上一级为2 等等
	 * @param skipStackTraceInt 起始堆栈段
	 * @return 堆栈信息
	 * 2006-2-21  15:36:25
	 */
	public static String getStackTraceString(
	        int traceLevelInt,Object obj) {
	    //导入参数合法化
	    if (obj == null) {
	        return "";
	    }
	    
	    //构造堆栈
	    Throwable throwable = new Throwable();
	    boolean printed = false; //是否输出了类明细
	    //构造返回信息值
	    StringBuffer returnSbf = new StringBuffer();
	    
	    returnSbf.append("类：")
	    	.append(obj.getClass().getName())
	    	.append(":\n");
	    if (traceLevelInt==0) {
	        return returnSbf.toString();
	    }
	    //构造堆栈深度
	    int stackTraceCount = throwable.getStackTrace().length;

	    int stackNo = 0; //堆栈指针
	    //构造堆栈信息
        for(int i=0; i < stackTraceCount; i++){
            StackTraceElement stacktraceelement = throwable.getStackTrace()[i];
            if (stacktraceelement.getClassName().equals(obj.getClass().getName())) {
                continue;
            }
            if (stackNo==traceLevelInt && traceLevelInt>0) {
                break;
            }
            stackNo++;
            if (!printed) {
                printed = true;
                returnSbf.append("类：行[");
            }
            returnSbf.append(
                    stacktraceelement.getFileName()).append(":")
                    		.append(stacktraceelement.getLineNumber()).append(" ");
            
        }
        if (printed) {
            returnSbf.append("]\n");
        }
	    return returnSbf.toString();
	}
	
	
	/**
	 * 容器中对应主键的值数组
	 * @author 刘虻
	 * 2007-4-1下午12:40:35
	 * @param keys 主键数组
	 * @param hasm 容器
	 * @return 对应的值数组
	 */
    public static Object[] getMapValues(
    						Object[] keys,Map<?,?> hasm) {
    	//获取返回序列
        List<?> valueList = getMapValueList(keys,hasm);
        //构造返回值
        Object[] reObjs = new Object[valueList.size()];
        //复制值
        valueList.toArray(reObjs);
        return reObjs;
    }
    
    
    
	/**
	 * 容器中对应主键的值序列
	 * @author 刘虻
	 * 2007-05-09上午11:14:00
	 * @param keyArrl 主键序列
	 * @param hasm 容器
	 * @return 对应的值序列
	 */
    @SuppressWarnings({ "unchecked", "rawtypes" })
	public static List<?> getMapValueList(Map <?,?>hasm) {
    	if (hasm==null) {
    		return new ArrayList();
    	}
    	return new ArrayList(hasm.values());
    } 
    
    
	/**
	 * 容器中对应主键的值序列
	 * @author 刘虻
	 * 2007-05-09上午11:14:00
	 * @param keys 主键数组
	 * @param hasm 容器
	 * @return 对应的值序列
	 */
    @SuppressWarnings({ "unchecked", "rawtypes" })
	public static List<Object> getMapValueList(Object[] keys,Map<?,?> hasm) {
        //导入参数合法化
        if (hasm == null 
                || hasm.isEmpty()) {
            return new ArrayList();
        }
        if (keys==null) {
        	return new ArrayList(hasm.values());
        }
        //构造返回值
        ArrayList<Object> reArrl = new ArrayList();
        //构建返回值
        for (int i=0;i<keys.length;i++) {
        	reArrl.add(hasm.get(keys[i]));
        }
        return reArrl;
    }
    
    
    /**
     * 将HashMap中的值转换为ArrayList
     * @author 刘虻
     * 2007-8-13上午11:14:33
     * @param hasm 源Map
     * @return 值序列
     */
    public static List<?> hashMapToList(Map<?,?> hasm) {
    	return getMapValueList((Object[])null,hasm);
    }
    
    
	/**
	 * 容器中对应主键的值序列
	 * @author 刘虻
	 * 2007-05-09上午11:14:00
	 * @param keyArrl 主键序列
	 * @param hasm 容器
	 * @return 对应的值序列
	 */
    public static ArrayList<?> getMapValueList(
    							List<?> keyArrl,Map<?,?> hasm) {
    	if (hasm==null) {
    		return new ArrayList<Object>();
    	}
    	
    	if (keyArrl==null) {
    		return new ArrayList<Object>(hasm.values());
    	}else {
    		//构造返回值
    		ArrayList<Object> reList = new ArrayList<Object>();
    		for (int i=0;i<keyArrl.size();i++) {
    			reList.add(hasm.get(keyArrl.get(i)));
    		}
    		return reList;
    	}
    } 
	
    
    /**
     * 合并两个容器（后面容器中的值覆盖前面容器值）
     * @author 刘虻
     * 2007-5-21下午05:11:54
     * @param mapOne 前容器
     * @param mapTwo 后容器
     * @param 是否将后容器中的内容放入前容器，然后返回前容器
     * @return 新容器
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static Map uniteMap(Map mapOne,Map mapTwo,boolean setFirst) {
    	
    	//构建返回值
    	Map reMap = null;
    	Object[] keys = null; //参数主键数组
    	
    	if (setFirst) {
    		reMap = mapOne;
    	}else {
    		reMap = new HashMap();
        	//获取前容器所有主键序列
        	
        	keys = getMapKeys(mapOne);
        	if (keys!=null) {
        		for (int i=0;i<keys.length;i++) {
        			reMap.put(keys[i],mapOne.get(keys[i]));
        		}
        	}
    	}
    	keys = getMapKeys(mapTwo);
    	if (keys!=null) {
    		for (int i=0;i<keys.length;i++) {
    			reMap.put(keys[i],mapTwo.get(keys[i]));
    		}
    	}
    	return reMap;
    }
    
    
	
	/**
     * 获得HashMap的主键数组（包含空主键）
     * @author 刘虻
     * @param hasm 需要获得主键数组的HashMap
     * @return 返回指定HashMap的主键数组 （包含空主键）
     * 2006-1-13  10:39:58
     */
    public static String[] getMapKeys(Map<String,?> hasm) {
    	//获取返回序列
    	List<String> keyList = getMapKeyList(hasm);
    	//构造返回值
    	String[] reObjs = new String[keyList.size()];
    	//复制值
    	keyList.toArray(reObjs);
    	return reObjs;
    }
    
    
    
	/**
     * 获得HashMap的主键序列（包含空主键）
     * @author 刘虻
     * @param hasm 需要获得主键数组的HashMap
     * @return 返回指定HashMap的主键序列 （包含空主键）
     * 2006-05-09 11:13:00
     */
    public static List<String> getMapKeyList(Map<?,?> hasm) {
    	if (hasm==null) {
    		return new ArrayList<String>();
    	}else {
    		try {
    		    //构建返回值
    		    ArrayList<String> reList = new ArrayList<String>();
    		    //获取主键对象
    		    Iterator<?> keys = hasm.keySet().iterator();
    		    while(keys.hasNext()) {
    		        reList.add(SString.valueOf(keys.next()));
    		    }
    			return reList;
    		}catch(Exception e) {
    			//偶尔发生找不到元素异常
    			return new ArrayList<String>();
    		}
    	}
    }
    
    
	/**
     * 获得HashMap的主键序列（包含空主键）
     * @author 刘虻
     * @param hasm 需要获得主键数组的HashMap
     * @return 返回指定HashMap的主键序列 （包含空主键）
     * 2006-05-09 11:13:00
     */
    public static List<String> keyList(Map<?,?> hasm) {
    	if (hasm==null) {
    		return new ArrayList<String>();
    	}else {
    		try {
    		    //构建返回值
    		    ArrayList<String> reList = new ArrayList<String>();
    		    //获取主键对象
    		    Iterator<?> keys = hasm.keySet().iterator();
    		    while(keys.hasNext()) {
    		        reList.add(SString.valueOf(keys.next()));
    		    }
    			return reList;
    		}catch(Exception e) {
    			//偶尔发生找不到元素异常
    			return new ArrayList<String>();
    		}
    	}
    }
    
    
    
    /**
     * 获得HashMap的主键数组（包含空主键）字符串型主键
     * @author 刘虻
     * 2007-3-19下午12:22:44
     * @param hasm 需要获得主键数组的HashMap
     * @return 返回指定HashMap的主键数组 （包含空主键）字符串型主键
     */
    public static String[] getMapKeyStrings(Map<String,?> hasm) {
    	return (String[])toObjectArray(getMapKeys(hasm),String.class);
    }
    
    /**
     * 获取HashMap主键数组中对应的值字符串数组
     * @author 刘虻
     * 2007-4-1下午12:43:24
     * @param keys 主键数组
     * @param hasm 容器
     * @return 对应的字符串值数组
     */
    public static String[] getMapValueStrings(Object[] keys,HashMap<?,?> hasm) {
    	return (String[])toObjectArray(getMapValues(keys,hasm),String.class);
    }
    
    /**
     * HashMap值转换成对象数组
     * @author 刘虻
     * @param hasm 对象
     * @return 对应的数组
     * 2006-3-28  19:06:00
     */
    public static Object[] mapToArray(Map<?,?> hasm,Class<?> cls) {
        //获得元素序列容器
        List <?>arrl = getMapValueList((Object[])null,hasm);
        if (arrl != null) {
            Object[] objs = new Object[arrl.size()];
            arrl.toArray(objs); //生成数组
            return toObjectArray(objs,cls); //转换
        }
        return null;
    }

    
    
    /**
     * 检测字符串中是否存在字符串数组中的字符
     * 比如：  字符串 "aaaaabbbaaaa"  字符串数组{"bbb","ccc"}
     * 			返回结果为 true
     * @author 刘虻
     * @param aString 待操作的字符串
     * @param inStrings 需要检测是否存在的字符串数组
     * @return true 存在   false 不存在
     * 2006-1-17  18:15:56
     */
    public static boolean checkStringInChars(
            String aString
            ,String[] inStrings) {
        //导入参数合法化
        if (aString == null 
                || inStrings == null 
                || inStrings.length < 1) {
            return false;
        }
        //循环开始检查是否存在
        for (int aInt=0;aInt<inStrings.length;aInt++) {
            if (inStrings[aInt] != null 
                    && aString.indexOf(inStrings[aInt]) > -1) {
                return true;
            }
        }
        return false;
    }
    
    
    /**
     * 根据类名数组获得类数组
     * @author 刘虻
     * @param classNames 类名数组
     * @return 类数组
     * 2006-4-28  18:54:47
     */
    public static Class<?>[] getClassForClassName(
            String[] classNames) throws ClassNotFoundException {
        //导入参数合法化
        if (classNames == null) {
            return null;
        }
        //构造返回值数组
        Class<?>[] classes = 
            new Class[classNames.length];
       
        for (int i=0;i<classNames.length;i++) {
            classes[i] = Class.forName(classNames[i]);
        }
        return classes;
    }
    
    /**
     * 将Object数组转换为指定类型的数组
     * @author 刘虻
     * 2007-3-19下午12:17:09
     * @param srcObj 原Object数组
     * @param toArrayCls 将要转换的类型
     * @return 转换后指定类型的数组
     */
    public static Object[] toObjectArray(Object[] srcObj,Class<?> toArrayCls) {
    	if (srcObj==null || toArrayCls==null) {
    		return null;
    	}
    	Object reArray = Array.newInstance(toArrayCls,srcObj.length);
    	
    	for (int i=0;i<srcObj.length;i++) {
    		((Object[])reArray)[i] = srcObj[i];
    	}
    	return (Object[])reArray;
    }
    
    /**
     * 将序列转换为逗号分割的字符串
     * 刘虻
     * 2012-11-27 下午4:10:07
     * @param list 指定序列
     * @return 用逗号分割的字符串
     */
    public static String listToString(List<?> list) {
    	//构建返回值
    	StringBuffer reSbf = new StringBuffer();
    	if(list!=null) {
    		for(int i=0;i<list.size();i++) {
    			if(i>0) {
    				reSbf.append(",");
    			}
    			reSbf.append(SString.valueOf(list.get(i)));
    		}
    	}
    	return reSbf.toString();
    }
    
    /**
     * 过滤字符串数组中的一组字符串
     * 比如：  要操作的字符串为 {"ccbbcaacbbcaacc","ddddaadddbbdddaadd"}
     * 		  需要过滤掉的字符串数组 {"aa","bb"}
     * 	      结果为：{"cccccccc","dddddddd"}
     * @author 刘虻
     * @param sourceStrs  需要操作的字符串数组
     * @param leachCharStrs 需要过滤掉的字符串数组
     * @return 过滤后的字符串数组 
     * 2006-1-17  17:28:50
     */
    public static String[] leachChars(
            String[] sourceStrs
            ,String[] leachCharStrs) {
        
        //导入参数合法化
        if (sourceStrs == null || sourceStrs.length < 1) {
            return null;
        }
        if (leachCharStrs == null || leachCharStrs.length < 1) {
            return sourceStrs;
        }
        //循环每一个需要替换的字符串
        for (int aInt=0;aInt<sourceStrs.length;aInt++) {
            sourceStrs[aInt] = leachChar(sourceStrs[aInt],leachCharStrs);
        }
        return sourceStrs;
    }
    
    
    /**
     * 过滤掉字符串中的一组字符
     * 比如 "aaaaabbaccabbaaabbaa"  要过滤掉 {"aa","cc"}  结果为"aaaaaaaaaaa"
     * @author 刘虻
     * @param sourceStr 需要操作的字符串
     * @param leachCharStrs 需要过滤掉的字符数组
     * @return 操作后的字符串
     * 2006-1-17  17:42:19
     */
    public static String leachChar(
            String sourceStr
            ,String[] leachCharStrs) {
        //导入参数合法化
        if (sourceStr == null 
                || sourceStr.length()==0
                || leachCharStrs == null
                || leachCharStrs.length < 1) {
            return sourceStr;
        }
        //循环过滤每一个需要过滤的字符
        for (int aInt=0;aInt<leachCharStrs.length;aInt++) {
            sourceStr = swapString(sourceStr,leachCharStrs[aInt],"");
        }
        return sourceStr;
    }
    
    
    
    /**
     * 替换字符串中指定的字符
     * @author 刘虻
     * @param strString 要操作的字符串
     * @param strSub 需要替换的字符串
     * @param strTo 替换成的字符串
     * @return 替换后的字符串
     * 2006-1-5  10:10:04
     */
    public static String swapString(String str,String fromStr,String toStr) {
        //导入参数合法化
        if (str==null) {
            return "";
        }
      //将待处理字符串按照替换字符进行分割
        String[] strs = split(str,fromStr);
      //准备拼装返回值
        StringBuffer reStr = new StringBuffer();
        if (strs!=null && strs.length>0) {
            for (int i=0;i<strs.length;i++) {
                reStr.append(strs[i]); 
                if (i<strs.length-1) {
                    reStr.append(toStr); 
                }
            }
        }
        return reStr.toString();
    }
    
    
    /**
     * 替换字符串中指定的字符
     * @param str 要操作的字符串
     * @param swpStrs 需要替换的字符串和替换成的字符串
     * @return  替换后的字符串
     * 2018年9月17日
     * @author MBG
     */
    public static String swap(String str,String... swpStrs) {
        //导入参数合法化
        if (str==null || swpStrs==null || swpStrs.length<2) {
            return str;
        }
        for(int i=0;i<swpStrs.length;i+=2) {
            str = swapString(str,swpStrs[i],swpStrs[i+1]);
        }
        return str;
    }
    
    
    /**
     * 替换字符串中指定的字符
     * @author 刘虻
     * @param strString 要操作的字符串
     * @param strSub 需要替换的字符串
     * @param strTo 替换成的字符串
     * @return 替换后的字符串
     * 2006-1-5  10:10:04
     */
    public static String swapString(String str,String... swpStrs) {
        //导入参数合法化
        if (str==null || swpStrs==null || swpStrs.length<2) {
            return str;
        }
        for(int i=0;i<swpStrs.length;i+=2) {
            str = swapString(str,swpStrs[i],swpStrs[i+1]);
        }
        return str;
    }
    
    /**
     * 替换字符串中指定的字符
     * @author 刘虻
     * 2007-1-4下午02:11:26
     * @param str 源字符串
     * @param fromStrs 指定字符串数组
     * @param toStrs 要替换的字符串数组
     * @return 替换后的字符串数组
     */
    public static String swapString(String str,String[] fromStrs,String[] toStrs) {
    	if (fromStrs!=null 
    			&& toStrs!=null 
    			&& fromStrs.length==toStrs.length) {
    		for (int i=0;i<fromStrs.length;i++) {
    			str = swapString(str,fromStrs[i],toStrs[i]);
    		}
    	}
    	return str;
    }
    
    
    

    /**
     * 将字符串转换为URL提交的字符串
     * @author 刘虻
     * @param valueStr 待处理的字符串
     * @return 处理后的URL字符串  %AB%CD
     * 2006-5-25  15:46:34
     */
    public static String urlEncoding(String valueStr) {
        //导入参数合法化
        if (valueStr == null) {
            return null;
        }
        //构造返回值
        StringBuffer sbf = new StringBuffer();
        
        //将字符串拆成每个字进行处理
        for (int i=0;i<valueStr.length();i++) {
            //取当前字
            String thisStr = valueStr.substring(i,i+1);
            //转换为字节
            byte[] strBytes = thisStr.getBytes();
            if (strBytes.length == 1) {
                //直接输出单字节的字
                sbf.append(thisStr); //单字符
            }else {
                //多字符
	            for (int j=0;j<strBytes.length;j++) {
	                sbf.append("%").append(
	                    (Integer.toHexString(
								strBytes[j] & 0xff)).toUpperCase());
	            }
            }
        }
        return sbf.toString();
    }
    
    
    /**
     * 将字符串转换为Int型，非int型字符串的返回值为0
     * @author 刘虻
     * @param valueStr 待转换的字符串
     * @return 转换后的值
     * 2006-6-13  10:12:57
     */
    public static int stringToInt(String valueStr) {
    	int reInt = 0;
    	try {
    		reInt = Integer.parseInt(valueStr);
    	}catch(Exception e) {}
    	return reInt;
    }
    
    
    /**
     * 将字符串转换为long型，非long型字符串的返回值为0
     * @author 刘虻
     * @param valueStr 待转换的字符串
     * @return 转换后的值
     * 2006-6-13  10:12:57
     */
    public static long stringToLong(String valueStr) {
    	long reLon = 0;
    	try {
    		reLon = Long.parseLong(valueStr);
    	}catch(Exception e) {}
    	return reLon;
    }

    
    /**
     * 将字符串转换为double型，非double型字符串的返回值为0
     * @author 刘虻
     * @param valueStr 待转换的字符串
     * @return 转换后的值
     * 2006-6-13  10:12:57
     */
    public static double stringToDouble(String valueStr) {
    	double reDou = 0;
    	try {
    		reDou = Double.parseDouble(valueStr);
    	}catch(Exception e) {}
    	return reDou;
    }
    
    
    /**
     * 比较objBytes 是否在 srcBytes 的末尾
     * @author 刘虻
     * 2007-5-25上午11:35:48
     * @param srcBytes 源数组
     * @param endSize 源素组中，最后一个字节位置
     * @param objBytes 比较数组
     * @return  true在末尾 false不在末尾
     */
    public static boolean endWithBytes(byte[] srcBytes,int endSize,byte[] objBytes) {
    	
    	
    	//两个数组同时为空
    	if (srcBytes == null && objBytes == null) {
    		return true;
    	}
    	//两个数组其中一个为空
    	if (srcBytes == null || objBytes == null) {
    		return false;
    	}
    	//数组元素数量不等
    	if (srcBytes.length < objBytes.length) {
    		return false;
    	}
    	int objSize = objBytes.length;
    	if (endSize<0) {
    		endSize = srcBytes.length;
    	}
    	for (int i=1;i<objSize+1;i++) {
    		if (srcBytes[endSize-i] != objBytes[objSize-i]) {
    			return false;
    		}
    	}
    	return true;
    	
    }
    
    
    /**
     * 比较objBytes 是否在 srcBytes 的末尾
     * @author 刘虻
     * 2007-5-25上午11:35:48
     * @param srcBytes 源数组
     * @param objBytes 比较数组
     * @return  true在末尾 false不在末尾
     */
    public static boolean endWithBytes(byte[] srcBytes,byte[] objBytes) {
    	return endWithBytes(srcBytes,-1,objBytes);
    }
    
    
    
    /**
     * 比较objBytes 是否在 srcBytes 的开头
     * @author 刘虻
     * 2007-5-25上午09:34:39
     * @param srcBytes 源数组
     * @param objBytes 比较数组
     * @return true在开头 false不在开头
     */
    public static boolean startsWithBytes(byte[] srcBytes,byte[] objBytes) {
    	
    	//两个数组同时为空
    	if (srcBytes == null && objBytes == null) {
    		return true;
    	}
    	//两个数组其中一个为空
    	if (srcBytes == null || objBytes == null) {
    		return false;
    	}
    	//数组元素数量不等
    	if (srcBytes.length < objBytes.length) {
    		return false;
    	}
    	for (int i=0;i<objBytes.length;i++) {
    		if (srcBytes[i] != objBytes[i]) {
    			return false;
    		}
    	}
    	return true;
    }
    
    /**
     * 比较两个字节数组是否相同
     * @author 刘虻
     * @param aBytes 字节数组A
     * @param bBytes 字节数组B
     * @return 相同返回真（包括两个字节数组同时为空） 不同返回假
     * 2006-6-26  17:16:48
     */
    public static boolean equalsBytes(byte[] aBytes,byte[] bBytes) {
    	
    	//两个数组同时为空
    	if (aBytes == null && bBytes == null) {
    		return true;
    	}
    	//两个数组其中一个为空
    	if (aBytes == null || bBytes == null) {
    		return false;
    	}
    	//数组元素数量不等
    	if (aBytes.length != bBytes.length) {
    		return false;
    	}
    	for (int i=0;i<aBytes.length;i++) {
    		if (aBytes[i] != bBytes[i]) {
    			return false;
    		}
    	}
    	return true;
    }
    
    /**
     * 根据分割字节数组，将源字节数组分割开来
     * 原字节数组开头必须为分割字节数组，否则返回空
     * @author 刘虻
     * @param keyBytes 分割字节数组
     * @param sourceBytes 原字节数组
     * @return 分割后的字节数组  element byte[]
     * 2006-6-16  17:27:02
     */
    public static ArrayList<byte[]> splitBytes(byte[] sourceBytes,byte[] keyBytes) {
    	//构造返回值
    	ArrayList<byte[]> reArrayList = new ArrayList<byte[]>();
    	
    	//导入参数合法化
    	if (sourceBytes == null 
    			|| keyBytes == null) {
    		return null;
    	}
    	//原字节数组字节总数
    	int sourceByteCountInt = sourceBytes.length;
    	//分割字节数组字节总数
    	int keyByteCountInt = keyBytes.length;
    	
    	//导入参数合法化
    	if (sourceByteCountInt < 1 
    			|| keyByteCountInt < 1 
    			|| sourceByteCountInt < keyByteCountInt) {
    		return null;
    	}
    	
    	int byteNoInt = 0; //原字节数组指针
    	//循环检查原字节数组开头是否为分割字节数组
    	for (int i=0;i<keyByteCountInt;i++) {
    		if (sourceBytes[byteNoInt] != keyBytes[i]) {
    			return null;
    		}
    		byteNoInt++; //原字节数组指针后移
    	}
    	
    	int startByteNoInt = byteNoInt; //记录开始分段位置
    	boolean isNextBoo = false; //是否设置下一起始分段位置
    	boolean isFoundBoo = false; //是否发现分段结束位置
    	
    	//循环分割
    	while (sourceByteCountInt > byteNoInt) {
    		isFoundBoo = true; //暂时标记已经发现
    		if (isNextBoo) {
    			startByteNoInt = byteNoInt; //记录开始分段位置
    			isNextBoo = false;
    		}
    		if (sourceByteCountInt-byteNoInt>keyByteCountInt) {
    			//当剩下的字节数大于分割字节数时
    			for (int i=0;i<keyByteCountInt;i++) {
    				if (sourceBytes[byteNoInt] != keyBytes[i]) {
    					isFoundBoo = false; //标记没发现
    					break;
    				}
    				byteNoInt++; //原字节数组指针后移
    			}
    			if (!isFoundBoo) {
    				byteNoInt++; //原字节数组指针后移
    				continue;
    			}
    			//构造分段数组
    			byte[] thisBytes = 
    				new byte[byteNoInt-startByteNoInt-keyByteCountInt];
    			for (int i=0;i<thisBytes.length;i++) {
    				thisBytes[i] = sourceBytes[startByteNoInt+i];
    			}
    			//将分段字节数组放入容器中
    			reArrayList.add(thisBytes);
    			//标记重新记录分段起始位置
    			isNextBoo = true;
    		}else {
    			//构造分段数组
    			byte[] thisBytes = 
    				new byte[sourceByteCountInt-startByteNoInt];
    			for (int i=0;i<thisBytes.length;i++) {
    				thisBytes[i] = sourceBytes[startByteNoInt+i];
    			}
    			//将分段字节数组放入容器中
    			reArrayList.add(thisBytes);
    			break;
    		}
    	}
    	return reArrayList;
    }
    
    
    /**
     * 将当前的字节数组重新定义为规定的字节数组
     * 如果规定数组元素数量小于原有数组元素数量，则忽略规定数量后的元素
     * 如果大于原有数组数量，则用为初始化元素填充
     * @author 刘虻
     * @param sourceBytes 原字节数组
     * @param newBytesCountInt 规定新的数组元素数量
     * @return 新的字节数组元素
     * 2006-6-27  9:16:55
     */
    public static byte[] reDimBytes(
    		byte[] sourceBytes,int newBytesCountInt) {
    	//构造返回数组
    	byte[] reBytes = new byte[newBytesCountInt];
    	//循环设置数组次数
    	int newCountInt = newBytesCountInt;
    	if (sourceBytes != null) {
    		//如果原数组元素数量小于新数组元素数量
    		if (sourceBytes.length < newBytesCountInt) {
    			newCountInt = sourceBytes.length;
    		}
    		for (int i=0;i<newCountInt;i++) {
    			reBytes[i] = sourceBytes[i];
    		}
    	}
    	return reBytes;
    }
    
    
    /**
     * 从数组开始截取指定长度的元素生成新的数组
     * @author 刘虻
     * @param sourceBytes 源数组
     * @param beforeNumberInt 指定数组长度
     * @return 截取后的新数组
     * 2006-6-29  15:28:48
     */
    public static byte[] beforeElement(
    		byte[] sourceBytes
    		,int startNumberInt
    		,int countInt) {
    	//参数合法化
    	if (sourceBytes == null) {
    		return null;
    	}
    	//循环取值次数
    	int whileCountInt = countInt;
    	//剩余元素数
    	int lastCountInt = sourceBytes.length - startNumberInt;
    	if (lastCountInt < 0) {
    		return null;
    	}
    	//如果源数组元素数量小于指定取的长度
    	if (lastCountInt < countInt) {
    		whileCountInt = lastCountInt;
    	}
    	//构造返回数组
    	byte[] reBytes = new byte[whileCountInt];
    	int j = 0; //返回元素数组指针
    	//执行循环取值
    	for (int i=startNumberInt;i<startNumberInt+whileCountInt;i++) {
    		reBytes[j] = sourceBytes[i];
    		j++;
    	}
    	return reBytes;
    }

    
	/**
	 * 将源字符串中，通过空格字符串分割为字符串数组
	 * "aaa bbb   ccc    ddd  eee fff='a  aa' "
	 * "aaa" "bbb" "ccc" ddd" eee" "fff='a" aa'"
	 * @author 刘虻
	 * @param source 源字符串
	 * @return 分割后的字符串数组
	 * 2006-7-20  20:12:36
	 */
	public static String[] splitSpace(String source) {
		//导入参数合法化
		if (source == null) {
			return null;
		}
		//构建返回值
		ArrayList<String> reArrl = new ArrayList<String>();
		//字符串容器
		StringBuffer sbf = new StringBuffer();
		//读取一个字符的指针
		int point = 0;
		while (point < source.length()) {
			point++; //移动指针
			//获取一个字符
			String aChar = source.substring(point-1,point);
			//判断字符是否为空格
			if (" ".equals(aChar)) {
				if (sbf.length() > 0) {
					reArrl.add(sbf.toString()); //将字符串放入容器
					sbf = new StringBuffer();//初始化当前字符串容器
				}
				continue;
			}
			sbf.append(aChar);
		}
		//将剩下的字符串放入容器中
		if (sbf.length() > 0) {
			reArrl.add(sbf.toString());
		}
		//构建返回值
		String[] reStrs = new String[reArrl.size()];
		reArrl.toArray(reStrs);
		return reStrs;
	}
	
	
    /**
     * 字符串格式转换
     * Edit:刘虻
     * @param s 要转换的字符串
     * @param from  原来什么格式 ISO-8859-1,GB2312,UTF-8,GBK,UTF-16BE
     * 通常页面乱码采用  "ISO-8859-1"转"GB2312" 参数
     * @param to 要转成什么格式
     * @return
     * 2005-9-19  16:44:06
     */
    public static String encode(String s, String from, String to) {
        String r = s;
        if (r != null) {
          try {
            r = new String(r.getBytes(from), to);
          } catch (Exception e) {
          }
        }
        return r;
      }
    
    
    /**
     * 打印异常对象信息
     * @author 刘虻
     * 2006-8-22下午12:14:02
     * @param e 异常
     * @return 异常对象信息
     */
    public static String getExceptionString(Throwable e) {
    	if (e==null) {
    		return "";
    	}
    	Throwable cause = e.getCause();
    	if(cause!=null) {
    		return getExceptionString(cause);
    	}
    	StringBuffer sbf = new StringBuffer();

    	sbf.append(e.getMessage());
    	sbf.append("\n");
    	sbf.append(e.toString());
    	sbf.append("\n");

    	return sbf.toString();
    }
	
    
    /**
     * 替换字符串中头一个关键字
     * @author 刘虻
     * 2006-8-30下午07:19:32
     * @param source 源字符串
     * @param swapChar 关键字
     * @param toChar 替换值
     * @return 替换后的字符串
     */
    public static String replaceFirstChar(
    		String source,String swapChar,String toChar) {
    	//导入参数合法化
    	if (source==null 
    			|| source.length()==0 
    			|| swapChar==null 
    			|| swapChar.length()==0 
    			|| toChar==null) {
    		return source;
    	}
    	
    	String reStr = ""; //构造返回值
    	int point = source.indexOf(swapChar);
    	if (point > -1) {
    		if (point>0) {
    			reStr = source.substring(0,point);
    		}
    		reStr += toChar;
    		
    		reStr += source.substring(point+toChar.length());
    	}
    	
    	return reStr;
    }
    
    
    /**
     * 基本错误日志方法
     * @author 刘虻
     * @param logStr 错误内容
     * 2006-7-11  17:07:21
     */
    public static void errorLog(String logStr,Object obj) {
    	System.err.println(getStackTraceString(-1,obj)+">"+logStr);
    }
    
    
    /**
     * 获取异常信息  如果没有异常信息，返回toString
     * @author 刘虻
     * 2007-10-9下午07:50:57
     * @param e 异常
     * @return 异常信息
     */
    public static String getExceptionMessage(Throwable e) {
    	if (e==null) {
    		return null;
    	}
    	//获取来源
    	Throwable cause = e.getCause();
    	if(cause!=null) {
    		return getExceptionMessage(cause);
    	}
    	//构建返回值
    	String reStr = e.getMessage();
    	if(reStr==null || reStr.length()<1) {
    		reStr = e.toString();
    	}
    	return reStr;
    }
    
    
    
    /**
     * 将目标序列中的不与原序列中重复的元素放入原序列中
     * @author 刘虻
     * 2007-11-2上午10:52:27
     * @param localList 原序列
     * @param otherList 目标序列
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static void addAllListNotRepeat(List localList,List otherList) {
    	if (localList==null || otherList==null) {
    		return;
    	}
    	for (Object element:otherList) {
    		if (element==null || localList.contains(element)) {
    			continue;
    		}
    		localList.add(element);
    	}
    }
    
    
    /**
     * 通过索引将指定对象序列进行排序
     * @author 刘虻
     * 2008-9-5下午02:44:57
     * @param indexArr 索引序列
     * @param objectList 目标对象序列
     * @return 排序后的序列
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static ArrayList fixObjectIndex(List indexArr,List objectList) {
    	//构建返回值
    	ArrayList reList = new ArrayList();
    	if (indexArr==null || indexArr.size()<1) {
    		if (objectList!=null) {
    			reList.addAll(objectList);
    		}
    		return reList;
    	}
    	//索引指针
    	int point = 0; 
    	boolean isFist = true; //是否首次比较
    	boolean hasAdd = false; //是否已经加入元素
    	//处理后的序号
    	ArrayList fixIndexList = new ArrayList();
    	
    	while(point<indexArr.size() && point<objectList.size()) {
    		
    		if (isFist) {
    			isFist = false;
    			reList.add(objectList.get(0));
    			fixIndexList.add(indexArr.get(0));
    			point++;
    			continue;
    		}
    		hasAdd = false;
    		//获取指定位置的索引值对象
    		Object pointObj = indexArr.get(point);
    		//索引值
    		int pointValue = SInteger.valueOf(indexArr.get(point));
    		for(int i=0;i<fixIndexList.size();i++) {
    			if (SInteger.valueOf(fixIndexList.get(i))>pointValue) {
    				fixIndexList.add(i,pointObj);
    				reList.add(i,objectList.get(point));
    				point++;
    				hasAdd = true;
    				break;
    			}
    		}
    		if (hasAdd) {
    			continue;
    		}
    		fixIndexList.add(pointObj);
    		reList.add(objectList.get(point));
    		point++;
    	}
    	return reList;
    }
    
    /**
     * 将数组转换为序列
     * 刘虻
     * 2013-4-16 下午4:55:55
     * @param array 数组
     * @return 序列
     */
    public static ArrayList<Object> arrayToList(Object[] array) {
    	//构建返回值
    	ArrayList<Object> reList = new ArrayList<Object>();
    	if(array!=null) {
    		for(int i=0;i<array.length;i++) {
    			reList.add(array[i]);
    		}
    	}
    	return reList;
    }
    
    //#region trim(str,...trimStrs) 除去指定字符串首尾的指定字符
    /**
     * 除去指定字符串首尾的指定字符
     * @param str			指定字符串
     * @param trimStrs		指定字符（可以是多个字符）
     * @return				处理后的字符串
     * 2014年7月29日
     * @author 椹疂鍒?
     */
    public static String trim(String str,String... trimStrs) {
    	if(str==null) {
    		return "";
    	}
    	// 是否再处理一次
    	boolean again = true;
    	while(again) {
    		again = false;
    		
  	    	for(String trimStr:trimStrs) {
	    		if(str.startsWith(trimStr)) {
	    			str = str.substring(1);
	    			again = true;
	    		}
	    		if(str.endsWith(trimStr)) {
	    			str = str.substring(0,str.length()-1);
	    			again = true;
	    		}
	    	}
    	}
    	return str;
    }
    //#endregion
    
    
    /**
     * 移除List中的空或空字符串元素
     * @param list 待处理的list
     * @return 处理后的list
     * 2017年12月5日
     * @author MBG
     */
    public static List<String> fixEmptyList(List<String> list) {
    	if(list==null) {
    		return new ArrayList<String>();
    	}
    	int i = 0;
    	String ele;
    	while(i<list.size()) {
    		ele = list.get(i);
    		if(ele==null || ele.length()<1) {
    			list.remove(i);
    			continue;
    		}
    		i++;
    	}
    	return list;
    }
    
	/**
	 * 将内存数据转换为可读的内存数据
	 * @param size 内存数值
	 * @return 可读的内存数值
	 * 2018年1月16日
	 * @author MBG
	 */
	public static String memorySize(double size) {
		int suffix = 0;
		while(size>1024) {
			suffix++;
			size = size/1024;
		}
		String suffixStr;
		switch(suffix) {
			case 0:
				suffixStr = "B";
				break;
			case 1:
				suffixStr = "K";
				break;
			case 2:
				suffixStr = "M";
				break;
			case 3:
				suffixStr = "G";
				break;
			case 4:
				suffixStr = "T";
				break;
			case 5:
				suffixStr = "P";
				break;
			default:
				suffixStr = "-";
		}
		return SDouble.cut(size,2)+suffixStr;
	}
}
